Notebook dedicado a la detección de objetos en el conjunto de imagenes personales de estudio. Los datos obtenidos mediante el uso de la librería YOLO y sus modelos preentrenados serán cargados en un grafo para realizar distintos analisis descriptivos y poder persistir la información en ficheros gml.
import os.path
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
from PIL import Image
# Packages propios
from utils.objectdetection import ObjectDetectionHelper
from utils.graphdbmanipulation import ImagesGraphDB
from utils.imagesmanipulation import ImageHelper
# Rutas de interés
PATH_IMAGENES_A_ANALIZAR = "./resources/images/Movil-S21"
PATH_MODELO_YOLO = "./models/yolov8m.pt"
PATH_DETECTED_LABELS ='./resources/images/Movil-S21_labels_predicted_COCO'
PATH_LABELS_REF_FILE ='./resources/coco_labels.csv'
PATH_MANUAL_LABELS_FILE= './resources/etiquetado_imagenes.xlsx'
PATH_GML_FILE = 'c:/Users/dcsj/Repositorios/UOC_TFM/image_classifier/outputs/graphs/graph_OBJECTS.gml'
Dentro del package utils generado para el proyecto hay clases que ayudan a la realización de diversas acciones sobre las imágenes utilizadas. Una de estas acciones que se facilitan es el redimensionamiento de imágenes. Las imágenes redimensionadas se usarán para mostrar resultados en el notebook con imagenes menos "pesadas".
ImageHelper.resize_images(PATH_IMAGENES_A_ANALIZAR,'resized',640,640)
Se ha creado la clase ObjectDetectionHelper para ayudar en la detección de objetos mediante el uso del package ultralytics que implementa YOLO.
Se usa el modelo yolov8m de la librería YOLO v8 para detectar todas las clases preentrenadas. Los resultados de predicciones acabarán en una carpeta "runs/detect/predict" un nivel por encima de la de proyecto. En la subcarpeta de "labels" dejará en formato txt ficheros que definen los "bounding boxes" y la clase de los mismos para cada una de las imágenes. Los tipos de objetos que yolo puede detectar se pueden ver en el fichero "labels.txt".
# Se crea el objeto ObjectDetector que ayudará en toda la gestión de detección de objetos
objectdetector = ObjectDetectionHelper()
objectdetector.detectionTrainedClasses(PATH_MODELO_YOLO,PATH_IMAGENES_A_ANALIZAR)
# Se crea un objeto de la clase ImagesAnalyzedLoader para cargar la información
imagesGraphDB = ImagesGraphDB()
# Se cargan el grafo con los objetos detectados en cada imagen
imagesGraphDB.load_graph_from_yolo_detected_objects_txt_files(PATH_LABELS_REF_FILE,PATH_DETECTED_LABELS)
# Se guarda el grafo en la carpeta de "outputs" en fichero gml
imagesGraphDB.write_gml_file(PATH_GML_FILE)
# Se cargan los datos desde un fichero gml
imagesGraphDB = ImagesGraphDB()
imagesGraphDB.load_graph_from_gml_file(PATH_GML_FILE)
%matplotlib inline
object_classes_interest = ['person','bottle','wine glass','fork','knife','spoon','bowl','cake','chair','dining table','vase']
nodes = imagesGraphDB.get_nodes() #devuelve un diccionario iterable
object_class_names = []
number_images_with_class_ocurrence =[]
for node in nodes:
if node in object_classes_interest :
neighbors = imagesGraphDB.get_neighbours(node)
object_class_names.append(node)
number_images_with_class_ocurrence.append(len(list(neighbors)))
fig, ax = plt.subplots(figsize=(5,5))
fig.suptitle('Number of images with object type ocurrences')
ax.bar(object_class_names,number_images_with_class_ocurrence)
plt.xticks(rotation=30, ha='right')
for i in range(len(object_class_names)):
plt.text(x = i-0.3 , y = number_images_with_class_ocurrence[i], s = number_images_with_class_ocurrence[i], size = 8)
plt.show()
# Se obtiene las imágenes del grafo que se relacionan con los nodos "person" y "cake"
object_classes_to_filter = ['cake','person'] # Se cogerán las imagenes con pastels y personas
neighbors_cake = imagesGraphDB.get_images_containing_list_object_types(object_classes_to_filter)
cake_images_filepath_list = []
cake_images_filename_list = []
for neighbor_cake in neighbors_cake:
cake_images_filepath_list.append(os.path.join(PATH_IMAGENES_A_ANALIZAR,'resized',neighbor_cake))
cake_images_filename_list.append(neighbor_cake)
# Se cargan las imágenes en formato PIL en una lista pora poderlas mostrar en un grid
images_rgb_list= []
for i, image in enumerate(cake_images_filepath_list):
image_rgb = Image.open(image)
images_rgb_list.append(image_rgb)
# Se muestran las imagenes en un grid usando un metodo propio del helper de imágenes
%matplotlib inline
ImageHelper.display_images(images_rgb_list,columns=3,max_images=20,label_font_size=12)